package expressions.slogo;

import java.util.ArrayList;
import java.util.List;
import exceptions.EvaluationException;
import expressions.Expression;
import expressions.IContext;
import expressions.Prefix;

/**
 * An prefix command that affects the turtle in some way. In order to do this,
 * subclasses will have an ITurtleContext to work with.
 * 
 * If the TurtleCommand is called with a different kind of context, it throws an
 * error.
 */
public abstract class TurtleCommand extends Prefix<Double>
{

    public TurtleCommand(int arguments)
    {
        super(arguments);
    }

    @Override
    public Double evaluate(IContext<Double> context)
    {
        List<Double> results = new ArrayList<Double>();

        for (Expression<Double> child : children)
        {
            results.add(child.evaluate(context));
        }

        if (context instanceof ITurtleContext)
        {
            return combineResults(results, (ITurtleContext) context);
        }
        else
        {
            throw new EvaluationException();
        }
    }

    /**
     * Combines the values returned by the children expressions into a value
     * that this expression should return.
     * 
     * @param results
     *            The children values.
     * @param context
     *            A context that allows the method to move the turtle, or to see
     *            its current attributes.
     * @return The value of this operator.
     */
    protected abstract Double combineResults(List<Double> results, ITurtleContext context);

}
